﻿
using CSharpLibs.Annotations;

namespace System.Collections.Generic
{
	[Builtin]
	public static class EqualityComparer<T0> : Object
	{
		[TypePatchNeeded]
		public static bool DefaultEquals(T0 x, T0 y)
		{ return false; }

		[TypePatchNeeded]
		public static int DefaultGetHashCode(T0 x)
		{ return 0; }
	}

	[Builtin]
	public static class ObjectEqualityComparerDefaultByRef<T0> where T0 : class
	{
		public static bool DefaultEquals(T0 x, T0 y)
		{ return x == y; }

		public static int DefaultGetHashCode(T0 x)
		{ return (x == null) ? 0 : x.dfhash; }
	}

	[Builtin]
	public static class ObjectEqualityComparer<T0> where T0 : class
	{
		public static bool DefaultEquals(T0 x, T0 y)
		{
			if(x != null)
				return ((y != null) && x.Equals(y));
			
			if(y != null)
				return false;

			return true;
		}

		public static int DefaultGetHashCode(T0 x)
		{ return (x == null ? 0 : x.GetHashCode()); }
	}

	[Builtin]
	public static class ObjectEqualityComparerWEQ<T0> where T0 : class, IEquatable<T0>
	{
		public static bool DefaultEquals(T0 x, T0 y)
		{
			if(x != null)
				return ((y != null) && x.Equals(y));

			if(y != null)
				return false;

			return true;
		}

		public static int DefaultGetHashCode(T0 x)
		{ return (x == null ? 0 : x.GetHashCode()); }
	}

	[Builtin]
	public static class NullableEqualityComparer<T0> where T0 : struct
	{
		public static bool DefaultEquals(Nullable<T0> x, Nullable<T0> y)
		{
			if(x.HasValue)
				return (y.HasValue && x.value.Equals(y.value));
		
			if(y.HasValue)
				return false;
			
			return true;
		}

		public static int DefaultGetHashCode(Nullable<T0> x)
		{ return x.HasValue ? x.value.GetHashCode() : 0; }
	}

	[Builtin]
	public static class StructEqualityComparerDefaultByValue<T0> where T0 : struct
	{
		[BuiltinMethod, BuiltinSemantics("valuetype_equals_static")]
		public static bool DefaultEquals(T0 x, T0 y)
		{ return false; }

		[BuiltinMethod, BuiltinSemantics("valuetype_hashcode_static")]
		public static int DefaultGetHashCode(T0 x)
		{ return -1; }
	}

	[Builtin]
	public static class StructEqualityComparer<T0> where T0 : struct
	{
		public static bool DefaultEquals(T0 x, T0 y)
		{ return x.Equals(y); }

		public static int DefaultGetHashCode(T0 x)
		{ return x.GetHashCode(); }
	}

	[Builtin]
	public static class StructEqualityComparerWEQ<T0> where T0 : struct, IEquatable<T0>
	{
		public static bool DefaultEquals(T0 x, T0 y)
		{ return x.Equals(y); }

		public static int DefaultGetHashCode(T0 x)
		{ return x.GetHashCode(); }
	}
}

